import { isNumber } from '@/utils/is.js'

/**
* @description 创建本地缓存对象
* @param { string } [prefixKey = '-']
* @param { Object } [storage = localStorage] - sessionStorage | localStorage
*/
// uni.setStorage()在H5中存储的是localStorage
export const createStorage = ({ prefixKey = '' } = {}) => {
  /**
  * @description 本地缓存类
  * @class Storage
  */
  const Storage = class {
    constructor() {
      this.prefixKey = prefixKey
      // #ifdef H5
      this.storage = sessionStorage
      // #endif
    }
    // 私有方法--将key小写-->大写
    _getKey(key) {
      return `${this.prefixKey}${key}`.toUpperCase()
    }
    /**
    * @description 设置缓存方法
    * @param {string} key 缓存键
    * @param {*} value 缓存值
    * @param expire 存活时间
    */
    set(key, value, expire = null) {
      if (expire && !isNumber(expire)) throw new Error('The third param must be Null or Number ')
      const stringData = JSON.stringify({
        value,
        expire: expire ? new Date().getTime() + expire * 1000 : null
      })
      uni.setStorageSync(this._getKey(key), stringData)
    }

    /**
    * @description 读取缓存方法
    * @param {string} key 缓存键
    * @param {*=} def 默认值
    * @returns { value } 要获取到的值
    */
    get(key, def = null) {
      let item = uni.getStorageSync(this._getKey(key))
      
      if (item) {
        try {
          const { value, expire } = JSON.parse(item)
          // 在有效期内直接返回
          if (expire === null || expire >= Date.now()) {
            return value
          }
          // value过期，清除
          this.remove(key)
        } catch (error) {
          return def
        }
      } else {
        return def
      }
    }

    /**
    * @description 删除缓存某一项
    * @param {string} key
    */
    remove(key) {
      uni.removeStorageSync(this._getKey(key))
    }

    /**
    * @description 清空所有缓存
    */
    clear() {
      uni.clearStorageSync()
    }

    // 以下方法只有H5才有的sessionStorage方法
    // #ifdef H5
    /**
    * @description session 设置缓存方法
    * @param {string} key 缓存键
    * @param {*} value 缓存值
    */
    sessionSet(key, value) {
      const stringData = JSON.stringify({ value })
      this.storage.setItem(this._getKey(key), stringData)
    }

    /**
    * @description 读取缓存方法
    * @param {string} key 缓存键
    * @param {*=} def 默认值
    * @returns { value } 要获取到的值
    */
    sessionGet(key, def) {
      let item = this.storage.getItem(this._getKey(key))
      if (item) {
        try {
          const { value } = JSON.parse(item)
          return value
        } catch (error) {
          return def
        }
      } else {
        return def
      }
    }

    /**
    * @description 删除缓存某一项
    * @param {string} key
    */
   sessionRemove(key) {
    this.storage.removeItem(this._getKey(key))
   }
   sessionClear() {
    this.storage.clear()
   }
  // #endif
  }
  return new Storage()
}

export const storage = createStorage()

export default storage